import { FC } from 'react'
import { useLocation, Navigate } from 'react-router-dom'
import { Spin } from 'antd'

import { useDispatch, useSelector } from 'react-redux'
import { useAppDispatch, useAppSelector } from '@/app/hooks'
import { getUserInfoAsync, logoutAsync, selectUser } from '@/pages/login/slice'
/*
  高阶组件HOC
    本质上是一个函数，接受组件作为参数，返回一个新组件

  WrappedComponent 组件是哪个？
    看路由路径（地址）
      /login --> EmptyLayout/Login
      /syt/dashboard --> Layout/Dashboard
*/
function withAuthorization(WrappedComponent: FC) {
  return () => {
    /*
      当用户登陆过（token）
        访问首页，没问题
          判断是否有用户数据
            有，没问题
            没有数据，请求数据，在展示
        访问登录页面，请跳转到首页
      当用户没有登录过
        访问首页，跳转到登录页面重新登录
        访问登录页面，没问题
    */
    const { token, name } = useAppSelector(selectUser)
    // const { token, name } = selectUser(store.getState())
    // console.log(token)
    // console.log(name)
    // 获取当前路由地址
    const { pathname } = useLocation()

    if (token) {
      // 说明登录过
      if (pathname === '/login' || pathname === '/') {
        return <Navigate to="/syt/dashboard" />
      }

      // 说明访问不能登录页面或/
      // 判断是否有用户数据
      if (name) {
        return <WrappedComponent />
      }

      // 说明没有用户数据
      const dispatch = useAppDispatch()
      // 请求用户数据
      ;(async () => {
        try {
          let re = await dispatch(getUserInfoAsync())
          // 判断返回值中是否含有error错误提示,如果有代表出现错误,直接抛出错误调用登出函数
          // 但是如果正常,可能会导致if判断不存在当前值然后报undefined错误,所以使用?判断
          // 可以简化为一个if判断返回值,但是懒得改
          if ((re as { error: any }).error?.message) {
            throw new Error((re as { error: any }).error.message)
          }
        } catch (error) {
          dispatch(logoutAsync())
        }
      })()

      return <Spin size="large" />
    } else {
      // 说明没有登录过
      if (pathname === '/login') {
        return <WrappedComponent />
      }

      // 说明访问不是登录页面
      return <Navigate to="/login" />
    }
  }
}

export default withAuthorization
